/**
 * Project Name cmpp-client
 * File Name Utils.java
 * Package Name com.lljqiu.tools.cmpp.client.utils
 * Create Time 2018年8月30日
 * Create by name：liujie -- email: liujie@lljqiu.com
 * Copyright © 2015, 2017, www.lljqiu.com. All rights reserved.
 */
package com.huxiaosu.tools.cmpp.utils;

import lombok.extern.slf4j.Slf4j;

import java.io.DataOutputStream;
import java.io.IOException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Date;

/**
 * Description
 *
 * @author liujie
 * @date 2024/4/20 14:11
 */
@SuppressWarnings("AlibabaLowerCamelCaseVariableNaming")
@Slf4j
public class Utils {

    private final static char[] HEX_DIGITS = "0123456789ABCDEF".toCharArray();

    public static String getNowData() {
        return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
    }

    public static String encryptMD5(String data) {
        return data == null ? null : hashEncrypt(data, "MD5");
    }

    /**
     * Description：hash 加密
     * @param data 待加密数据
     * @param algorithm 加密算法
     * @return String
     * @author name：liujie <br>
     * email: liujie@lljqiu.com
     **/
    private static String hashEncrypt(String data, String algorithm) {
        try {
            MessageDigest md = MessageDigest.getInstance(algorithm);

            return bytes2Hex(md.digest(data.getBytes()));
        }
        catch (Exception never) {
            throw new RuntimeException("加密失败");
        }
    }

    public static String bytes2Hex(byte[] bytes) {
        int len = bytes.length;
        char[] str = new char[len * 2];
        for (int i = 0; i < len; i++) {
            byte b = bytes[i];
            str[i * 2] = HEX_DIGITS[b >>> 4 & 0xF];
            str[i * 2 + 1] = HEX_DIGITS[b & 0xF];
        }
        return new String(str);
    }

    public static byte[] getAuthenticatorSource(String spId, String secret, String timestamp) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            String data = spId + "\0\0\0\0\0\0\0\0\0" + secret + timestamp;
            return md5.digest(data.getBytes());
        }
        catch (NoSuchAlgorithmException e) {
            return null;
        }
    }

    /**
     * Connect 成功后返回，其值通过单向MD5 hash计算得出，表示如下： AuthenticatorISMG
     * =MD5（Status+AuthenticatorSource+shared secret）
     * @return
     */
    public static byte[] getAuthenticatorISMG(int status, String authenticatorSourceStr, String secret) {
        try {
            MessageDigest md5 = MessageDigest.getInstance("MD5");
            byte[] data = (status + authenticatorSourceStr + secret).getBytes();
            return md5.digest(data);
        }
        catch (NoSuchAlgorithmException e) {

            return null;
        }
    }

    private static int sequenceId = 0;
    private static int MAX_SEQUENCE_ID = 255;

    /**
     * 序列 自增
     */
    public static int getSequence() {
        ++sequenceId;
        if (sequenceId > MAX_SEQUENCE_ID) {
            sequenceId = 0;
        }
        return sequenceId;
    }
    /**
     * 时间戳的明文,由客户端产生,格式为MMDDHHMMSS，即月日时分秒，10位数字的整型，右对齐 。
     */
    public static String getTimestamp() {
        DateFormat format = new SimpleDateFormat("MMddhhmmss");
        return format.format(new Date());
    }

    /**
     * 向流中写入指定字节长度的字符串，不足时补0
     *
     * @param dous:要写入的流对象
     * @param s:要写入的字符串
     * @param len:写入长度,不足补0
     */
    public static void writeString(DataOutputStream dous, String s, int len) {

        try {
            byte[] data = s.getBytes("gb2312");
            if (data.length > len) {
                log.error("向流中写入的字符串超长！要写长度={}字符串是={}" ,len, s);
            }
            int srcLen = data.length;
            dous.write(data);
            while (srcLen < len) {
                dous.write('\0');
                srcLen++;
            }
        } catch (IOException e) {
            log.error("向流中写入指定字节长度的字符串失 {}" , e.getMessage());
        }
    }
}
